package com.chat.webSocketUtils;

import java.io.IOException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArraySet;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.context.ContextLoader;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.chat.service.ChatMessageService;
import com.chat.vo.YzbChatMsg;


@ServerEndpoint("/yzbWebsocket/{keyValue}")
public class WebSocketHandler {

    @Autowired
    private ChatMessageService chatMessageService;
    //已读
    private static final String HAVE_READ = "2";
    //未读
    private static final String UN_READ = "1";
    //与某个客户端的连接会话，需要通过它来给客户端发送数据
    private Session session;
    //concurrent包的线程安全Set，用来存放每个客户端对应的MyWebSocket对象。
    //若要实现服务端与单一客户端通信的话，可以使用Map来存放，其中Key可以为用户标识
    private static CopyOnWriteArraySet<UserSocket> webSocketSet = new CopyOnWriteArraySet<UserSocket>();

    private ChatMessageService chatService = (ChatMessageService) ContextLoader.getCurrentWebApplicationContext().getBean("chatService");

    /**
     * 打开链接
     *
     * @param session
     */
    @OnOpen
    public void onOpen(@PathParam(value = "keyValue") String userName, Session session) {
        System.out.println("链接打开");
        this.session = session;
        UserSocket userSocket = new UserSocket(this, userName);
        //新建链接信息加入set里面
        webSocketSet.add(userSocket);
        System.out.println(JSONObject.toJSONString(webSocketSet));
    }

    @OnClose
    public void onClose() {
        while (webSocketSet.iterator().hasNext()) {
            if (webSocketSet.iterator().next().getWebSocket() == this) {
                webSocketSet.remove(webSocketSet.iterator().next());
                break;
            }
        }
        System.out.println("链接关闭");
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     * @param session 可选的参数
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        System.out.println("client message is: " + message);
        JSONObject msg = null;
        String to = "";
        String strMsg = "";
        try {
            msg = JSON.parseObject(message);
            //发送给
            to = msg.getString("to");
            strMsg = msg.getString("msg");
            System.out.println(to + "-------" + msg);
        } catch (Exception e) {
            e.printStackTrace();
        }

        String from = "";
        if (!StringUtils.isEmpty(to)) {
            for (UserSocket us : webSocketSet) {
                if (us.getWebSocket() == this) {
                    from = us.getSid();
                }
            }
            YzbChatMsg yzbChatMsg = new YzbChatMsg();
            for (UserSocket us : webSocketSet) {
                JSONObject sendMsg = new JSONObject();
                sendMsg.put("msg", strMsg);
                sendMsg.put("from", from);
                sendMsg.put("to", to);
                try {
                    System.out.println(JSON.toJSONString(strMsg + "    " + from));
                    if (session.isOpen()) {
                        us.getWebSocket().sendMessage(JSON.toJSONString(sendMsg));
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }

                if (to.equals(us.getSid())) {
                    yzbChatMsg.setIsRead(HAVE_READ);
                } else {
                    //如对方不在线 则作为未读插入记录 入数据库
                    yzbChatMsg.setIsRead(UN_READ);
                }

                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                yzbChatMsg.setId(uuid);
                yzbChatMsg.setMsg(strMsg);
                yzbChatMsg.setSender(from);
                yzbChatMsg.setAccept(to);
                yzbChatMsg.setCreateTime(Timestamp.valueOf(sdf.format(new Date())));
                yzbChatMsg.setImageUrl(null);
            }
            chatService.saveChatMessage(yzbChatMsg);
        }
    }

    /**
     * 发送
     *
     * @param message
     * @throws IOException
     */
    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
        //this.session.getAsyncRemote().sendText(message);
    }

    /**
     * 发生错误时调用
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        System.out.println("发生错误");
        error.printStackTrace();
    }
}
